/*******************************************************************************
 * Copyright(c) 2023 Levetop Semiconductor Co.,Led. All rights reserved.
 * @file     tftlcd.c
 * @author   UartTFT Application Team
 * @version  V0.0.1
 * @date     2023-01-12
 * @brief    This file contains the interface initialization and basic
 *           control functions of the TFT.
 ********************************************************************************/

#include "tftlcd.h"
#include "transport.h"
#include "function.h"
#include "dma.h"
#include "lt168_eic.h"	//QSPI_Vincent
#include "pit.h"		//QSPI_Vincent
//#include "edma_drv.h"
//#include "ioctrl_drv.h"
//#include "ccm_drv.h"
//#include "dmac_drv.h"




#include "lt168_dma.h"

void TFT_DataWrite_DMA(uint16_t *buf,uint16_t len)
{
//	*(volatile uint16_t*) (0x20000002)= data;


//	DMA_CH00_16bits_Write_start((u8*)&color_rea2);
//	DMA_CH00_wait();

	dma_tcd *test_ch = DMA_ADC_Channel;

	dma_control_config_ts dma_control_config;
	dma_tcd_config_ts dma_tcd_config;

	/* DMA 控制部分，使用默认配置 */
	DMA_Control_Reset(&dma_control_config);
	DMA_Control_Init(&dma_control_config);

	/* TCD 部分 */
	DMA_TCD_Reset(&dma_tcd_config);  //更改新配置之前必须清空该结构体

	/* DMA Channel */

	/* Source part---Start */
	dma_tcd_config.source = (uint32_t)&buf;		     // 源地址
	dma_tcd_config.source_modulo = DMA_MOD_Disable;		 // 设0则禁用，设 0<n<=31,则源地址低N位可以变，一般禁用比较鸡肋，无实际应用场合
	dma_tcd_config.source_datasize = DMA_DataSize_8bit;  // 源地址传输长度  0:8bit, 1:16bit, 2:32bit
	dma_tcd_config.source_offset = 1;					 // 每次向总线读取数据后源地址的偏移量 (带符号能向上、向下、不变)
	dma_tcd_config.source_last_address_adjustment = 0;	 // 大循环计数结束后，源地址写回到TCD的偏移量 (带符号能向上、向下、不变)
	/* Source part---End */

	/* Destination part---Start */
	dma_tcd_config.destin = (UINT32)0x20000002;		     // 目的地址
	dma_tcd_config.destin_modulo = DMA_MOD_Disable;		 // 设0则禁用，设 0<n<=31,则目的地址低N位可以变，一般禁用比较鸡肋，无实际应用场合
	dma_tcd_config.destin_datasize = DMA_DataSize_8bit; // 目的地址传输长度 0:8bit, 1:16bit, 2:32bit
	dma_tcd_config.destin_offset = 0;					 // 每次向总线写入数据后目的地址的偏移量 (带符号能向上、向下、不变)
	dma_tcd_config.destin_last_address_adjustment = 0;	 // 大循环计数结束后，目的地址写回到TCD的偏移量 (带符号能向上、向下、不变)
	/* Destination part---End */

//	dma_tcd_config.minor_transfer_num = len; /* 小循环传输数目 */
//	/* Major Loop--- */
//	dma_tcd_config.major_loop_num = 1;  /* 小循环次数 */
//	dma_tcd_config.d_req = 1;
	dma_tcd_config.minor_transfer_num = 1; /* 小循环传输数目 */
	/* Major Loop--- */
	dma_tcd_config.major_loop_num = len;  /* 小循环次数 */
	dma_tcd_config.d_req = 1;
//======================================= DMA ======================================
	DMA_TCD_Init(test_ch,&dma_tcd_config);
//	test_ch->BITER_LINK_ON |= (0x01);

	/* 开启通道的错误中断，判断配置是否出错 */
//	EIC->IER |= 1<<5;
//	DMA_Channel_Error_Interrupt_Enable(test_ch);
//
//	DMA_Channel_Hardware_Request_Enable(test_ch);
//	DMA_Channel_Clear_Done(test_ch);

//	Bit_Set(s->BAUD,SCI_BAUD_TDMAE_MASK);// tx dma

//		/* 手动清除通道的done位 */

	/* 软件启动 software start */
	DMA_Channel_Start(test_ch);

	while (DMA_Channel_Check_Donebit(test_ch) == 0) /* 直接等待大循环完成 */
	{
		asm("nop");
	}

//	Bit_Clear(s->BAUD,SCI_BAUD_TDMAE_MASK);// rx dma

}

// control RS pin of TFT
void LCD_RS(uint8_t bit)
{
	if (bit)
		LCD_RS_DATA;
	else
		LCD_RS_CMD;
}

// control CS pin of TFT
void LCD_CS(uint8_t bit)
{
	if (bit)
		LCD_CS_SET;
	else
		LCD_CS_RESET;
}

void SPI_LCD_RST_RESET(void)
{
	//UART_WriteGpioData(SCI2,UART_TX,Bit_RESET);			//RST
	EPORT0->EPDR &=~(1<<3);
}

void SPI_LCD_RST_SET(void)
{
	//UART_WriteGpioData(SCI2,UART_TX,Bit_SET);			//RST
	 EPORT0->EPDR |= (1<<3);
}

void SPI_LCD_CS_RESET(void)
{
	//UART_WriteGpioData(SCI2,UART_RX,Bit_RESET);			//CS
	EPORT0->EPDR &=~(1<<2);
}

void SPI_LCD_CS_SET(void)
{
	//UART_WriteGpioData(SCI2,UART_RX,Bit_SET);			//CS
	 EPORT0->EPDR |= (1<<2);
}


void SPI_LCD_SDA_RESET(void)
{
	//UART_WriteGpioData(SCI3,UART_RX,Bit_RESET);  //SDA
	EPORT0->EPDR &=~(1<<0);
}
void SPI_LCD_SDA_SET(void)
{
	//UART_WriteGpioData(SCI3,UART_RX,Bit_SET);  //SDA
	 EPORT0->EPDR |= (1<<0);
}


void SPI_LCD_SCL_RESET(void)
{
	//UART_WriteGpioData(SCI3,UART_TX,Bit_RESET); //SCL
	EPORT0->EPDR &=~(1<<1);
}
void SPI_LCD_SCL_SET(void)
{
	//UART_WriteGpioData(SCI3,UART_TX,Bit_SET); //SCL
	 EPORT0->EPDR |= (1<<1);
}


//???????
void SPI_SendData(unsigned char i)
{
   unsigned char n;

   for(n=0; n<8; n++)
   {
	  if(i&0x80) SPI_LCD_SDA_SET();
      	else     SPI_LCD_SDA_RESET();
      i<<= 1;

	  SPI_LCD_SCL_RESET();//_nop_(); _nop_();_nop_();_nop_();
      SPI_LCD_SCL_SET();//_nop_();_nop_();_nop_();_nop_();
   }
}

/********************************************************************************
 * Function Name	: TFT_DataWrite
 * Description  	: Send command to TFT.
 * Input        	: - cmd: command to be sent
 * Output       	: None
 * Return       	: None
 *********************************************************************************/
void TFT_CommandWrite(uint8_t cmd)
{
	SPI_LCD_CS_RESET();

    SPI_LCD_SDA_RESET();   //RS=0
	SPI_LCD_SCL_RESET();
	SPI_LCD_SCL_SET();      // 3?????
	SPI_SendData(cmd);
	SPI_LCD_CS_SET();

}

/********************************************************************************
 * Function Name	: TFT_DataWrite
 * Description  	: Send data to TFT.
 * Input        	: - data: data to be sent
 * Output       	: None
 * Return       	: None
 *********************************************************************************/
void TFT_DataWrite(uint8_t data)
{
	SPI_LCD_CS_RESET();

    SPI_LCD_SDA_SET();      //RS=1
	SPI_LCD_SCL_RESET();
	SPI_LCD_SCL_SET();      // 3?????
	SPI_SendData(data);
	SPI_LCD_CS_SET();

}

//SPI????????
void LCD_Port_Init(void)
{
	//UART_ConfigGpio(SCI2,UART_TX,GPIO_OUTPUT);             //RST
	//UART_ConfigGpio(SCI2,UART_RX,GPIO_OUTPUT);             //CS
	//UART_ConfigGpio(SCI3,UART_TX,GPIO_OUTPUT);            //SCL
	//UART_ConfigGpio(SCI3,UART_RX,GPIO_OUTPUT);            //SDA

	OPTION->ADCCDISR = 0x0000;
	OPTION->ADCCDISR = 0x4000;
	OPTION->ADCCDISR = 0x8000;
	OPTION->ADCCDISR = 0xC000;
	OPTION->ADCCDISR = 0xC0F7;
	OPTION->ADCCDISR |= 0xC0FF;//EPORT0[0~7]
	EPORT0->EPDDR &= ~0x40;    //EPORT06 input
	EPORT0->EPDDR |=  0x80;    //EPORT07 output

	EPORT0->EPDR |= 0x80;
	OPTION->CCR = 0x0000;
	OPTION->CCR = 0x0001;
	OPTION->CCR = 0x0002;
	OPTION->CCR = 0x0003;
	OPTION->CCR = 0x0403;
	EPORT1->EPDDR |= (1<<0);
	EPORT1->EPDR  |= (1<<0);
//	EPORT1->EPDR &=~(1<<0);

	EPORT0->EPDDR |= (1<<0);
	EPORT0->EPDDR |= (1<<1);
	EPORT0->EPDDR |= (1<<2);
	EPORT0->EPDDR |= (1<<3);

	SPI_LCD_CS_SET();
	SPI_LCD_RST_SET();
	SPI_LCD_SDA_SET();
	SPI_LCD_SCL_SET();
}


#define SPI_WriteComm  TFT_CommandWrite
#define SPI_WriteData  TFT_DataWrite
#define Delay          DelayMS
/********************************************************************************
 * Function Name	: LCD_TFT_Init
 * Description  	: Initialize screen.
 * Input        	: None
 * Output       	: None
 * Return       	: None
 *********************************************************************************/
void LCD_TFT_Init(void)
{

    LCD_Port_Init();

	SPI_LCD_RST_SET(); // RST
	DelayMS(10);
	SPI_LCD_RST_RESET();
	DelayMS(10);
	SPI_LCD_RST_SET();
	DelayMS(120); // Delay 120ms

	/*screen init,This should be adjusted according to the actual situation*/

#if 0//???
	/******************************************************************************/
	/* Panel Name : HSD4.0IPS(HSD040BPN1-A00)									  */
	/* Resulation : 480x480 													  */
	/* Inversion  : 2dot														  */
	/* Porch	  : vbp=15 , vfp=12 											  */
	/* Line Time  : 32us														  */
	/* Frame Rate : 60hz														  */
	/******************************************************************************/
	SPI_WriteComm(0xFF);
	SPI_WriteData(0x77);
	SPI_WriteData(0x01);
	SPI_WriteData(0x00);
	SPI_WriteData(0x00);
	SPI_WriteData(0x13);
	SPI_WriteComm(0xEF);
	SPI_WriteData(0x08);
	SPI_WriteComm(0xFF);
	SPI_WriteData(0x77);
	SPI_WriteData(0x01);
	SPI_WriteData(0x00);
	SPI_WriteData(0x00);
	SPI_WriteData(0x10);
	SPI_WriteComm(0xC0);
	SPI_WriteData(0x3B);
	SPI_WriteData(0x00);
	SPI_WriteComm(0xC1);
	SPI_WriteData(0x0D);
	SPI_WriteData(0x02);
	SPI_WriteComm(0xC2);
	SPI_WriteData(0x21);
	SPI_WriteData(0x08);
	SPI_WriteComm(0xCD);
	SPI_WriteData(0x08);//18-bit/pixel: MDT=0:D[21:16]=R,D[13:8]=G,D[5:0]=B(CDH=00) ;

						//				MDT=1:D[17:12]=R,D[11:6]=G,D[5:0]=B(CDH=08) ;
	SPI_WriteComm(0xB0);
	SPI_WriteData(0x00);
	SPI_WriteData(0x11);
	SPI_WriteData(0x18);
	SPI_WriteData(0x0E);
	SPI_WriteData(0x11);
	SPI_WriteData(0x06);
	SPI_WriteData(0x07);
	SPI_WriteData(0x08);
	SPI_WriteData(0x07);
	SPI_WriteData(0x22);
	SPI_WriteData(0x04);
	SPI_WriteData(0x12);
	SPI_WriteData(0x0F);
	SPI_WriteData(0xAA);
	SPI_WriteData(0x31);
	SPI_WriteData(0x18);
	SPI_WriteComm(0xB1);
	SPI_WriteData(0x00);
	SPI_WriteData(0x11);
	SPI_WriteData(0x19);
	SPI_WriteData(0x0E);
	SPI_WriteData(0x12);
	SPI_WriteData(0x07);
	SPI_WriteData(0x08);
	SPI_WriteData(0x08);
	SPI_WriteData(0x08);
	SPI_WriteData(0x22);
	SPI_WriteData(0x04);
	SPI_WriteData(0x11);
	SPI_WriteData(0x11);
	SPI_WriteData(0xA9);
	SPI_WriteData(0x32);
	SPI_WriteData(0x18);
	SPI_WriteComm(0xFF);
	SPI_WriteData(0x77);
	SPI_WriteData(0x01);
	SPI_WriteData(0x00);
	SPI_WriteData(0x00);
	SPI_WriteData(0x11);
	SPI_WriteComm(0xB0);
	SPI_WriteData(0x60);
	SPI_WriteComm(0xB1);
	SPI_WriteData(0x30);
	SPI_WriteComm(0xB2);
	SPI_WriteData(0x87);
	SPI_WriteComm(0xB3);
	SPI_WriteData(0x80);
	SPI_WriteComm(0xB5);
	SPI_WriteData(0x49);
	SPI_WriteComm(0xB7);
	SPI_WriteData(0x85);
	SPI_WriteComm(0xB8);
	SPI_WriteData(0x21);
	SPI_WriteComm(0xC1);
	SPI_WriteData(0x78);
	SPI_WriteComm(0xC2);
	SPI_WriteData(0x78);
	Delay(20);
	SPI_WriteComm(0xE0);
	SPI_WriteData(0x00);
	SPI_WriteData(0x1B);
	SPI_WriteData(0x02);
	SPI_WriteComm(0xE1);
	SPI_WriteData(0x08);
	SPI_WriteData(0xA0);
	SPI_WriteData(0x00);
	SPI_WriteData(0x00);
	SPI_WriteData(0x07);
	SPI_WriteData(0xA0);
	SPI_WriteData(0x00);
	SPI_WriteData(0x00);
	SPI_WriteData(0x00);
	SPI_WriteData(0x44);
	SPI_WriteData(0x44);
	SPI_WriteComm(0xE2);
	SPI_WriteData(0x11);
	SPI_WriteData(0x11);
	SPI_WriteData(0x44);
	SPI_WriteData(0x44);
	SPI_WriteData(0xED);
	SPI_WriteData(0xA0);
	SPI_WriteData(0x00);
	SPI_WriteData(0x00);
	SPI_WriteData(0xEC);
	SPI_WriteData(0xA0);
	SPI_WriteData(0x00);
	SPI_WriteData(0x00);
	SPI_WriteComm(0xE3);
	SPI_WriteData(0x00);
	SPI_WriteData(0x00);
	SPI_WriteData(0x11);
	SPI_WriteData(0x11);
	SPI_WriteComm(0xE4);
	SPI_WriteData(0x44);
	SPI_WriteData(0x44);
	SPI_WriteComm(0xE5);
	SPI_WriteData(0x0A);
	SPI_WriteData(0xE9);
	SPI_WriteData(0xD8);
	SPI_WriteData(0xA0);
	SPI_WriteData(0x0C);
	SPI_WriteData(0xEB);
	SPI_WriteData(0xD8);
	SPI_WriteData(0xA0);
	SPI_WriteData(0x0E);
	SPI_WriteData(0xED);
	SPI_WriteData(0xD8);
	SPI_WriteData(0xA0);
	SPI_WriteData(0x10);
	SPI_WriteData(0xEF);
	SPI_WriteData(0xD8);
	SPI_WriteData(0xA0);
	SPI_WriteComm(0xE6);
	SPI_WriteData(0x00);
	SPI_WriteData(0x00);
	SPI_WriteData(0x11);
	SPI_WriteData(0x11);
	SPI_WriteComm(0xE7);
	SPI_WriteData(0x44);
	SPI_WriteData(0x44);
	SPI_WriteComm(0xE8);
	SPI_WriteData(0x09);
	SPI_WriteData(0xE8);
	SPI_WriteData(0xD8);
	SPI_WriteData(0xA0);
	SPI_WriteData(0x0B);
	SPI_WriteData(0xEA);
	SPI_WriteData(0xD8);
	SPI_WriteData(0xA0);
	SPI_WriteData(0x0D);
	SPI_WriteData(0xEC);
	SPI_WriteData(0xD8);
	SPI_WriteData(0xA0);
	SPI_WriteData(0x0F);
	SPI_WriteData(0xEE);
	SPI_WriteData(0xD8);
	SPI_WriteData(0xA0);
	SPI_WriteComm(0xEB);
	SPI_WriteData(0x02);
	SPI_WriteData(0x00);
	SPI_WriteData(0xE4);
	SPI_WriteData(0xE4);
	SPI_WriteData(0x88);
	SPI_WriteData(0x00);
	SPI_WriteData(0x40);
	SPI_WriteComm(0xEC);
	SPI_WriteData(0x3C);
	SPI_WriteData(0x00);
	SPI_WriteComm(0xED);
	SPI_WriteData(0xAB);
	SPI_WriteData(0x89);
	SPI_WriteData(0x76);
	SPI_WriteData(0x54);
	SPI_WriteData(0x02);
	SPI_WriteData(0xFF);
	SPI_WriteData(0xFF);
	SPI_WriteData(0xFF);
	SPI_WriteData(0xFF);
	SPI_WriteData(0xFF);
	SPI_WriteData(0xFF);
	SPI_WriteData(0x20);
	SPI_WriteData(0x45);
	SPI_WriteData(0x67);
	SPI_WriteData(0x98);
	SPI_WriteData(0xBA);
	SPI_WriteComm(0xEF);
	SPI_WriteData(0x10);
	SPI_WriteData(0x0D);
	SPI_WriteData(0x04);
	SPI_WriteData(0x08);
	SPI_WriteData(0x3F);
	SPI_WriteData(0x1F);
	SPI_WriteComm(0xFF);
	SPI_WriteData(0x77);
	SPI_WriteData(0x01);
	SPI_WriteData(0x00);
	SPI_WriteData(0x00);
	SPI_WriteData(0x00);

	SPI_WriteComm(0x3A);
	SPI_WriteData(0x77);//55/50=16bit(RGB565);66=18bit(RGB666);77???????3AH??=24bit(RGB888)

	SPI_WriteComm(0xFF);
	SPI_WriteData(0x77);
	SPI_WriteData(0x01);
	SPI_WriteData(0x00);
	SPI_WriteData(0x00);
	SPI_WriteData(0x13);
	SPI_WriteComm(0xE8);
	SPI_WriteData(0x00);
	SPI_WriteData(0x0E);
	SPI_WriteComm(0xFF);
	SPI_WriteData(0x77);
	SPI_WriteData(0x01);
	SPI_WriteData(0x00);
	SPI_WriteData(0x00);
	SPI_WriteData(0x00);
	SPI_WriteComm(0x11);
	Delay(120);
	SPI_WriteComm(0xFF);
	SPI_WriteData(0x77);
	SPI_WriteData(0x01);
	SPI_WriteData(0x00);
	SPI_WriteData(0x00);
	SPI_WriteData(0x13);
	SPI_WriteComm(0xE8);
	SPI_WriteData(0x00);
	SPI_WriteData(0x0C);
	Delay(10);
	SPI_WriteComm(0xE8);
	SPI_WriteData(0x00);
	SPI_WriteData(0x00);

	SPI_WriteComm(0xFF);
	SPI_WriteData(0x77);
	SPI_WriteData(0x01);
	SPI_WriteData(0x00);
	SPI_WriteData(0x00);
	SPI_WriteData(0x00);
	SPI_WriteComm(0x29);

	SPI_WriteComm(0x36);
	SPI_WriteData(0x08);
	Delay(20);

#endif

}

//------------------------screen window----------------------------------------------------------
// X-axis coordinate offset: XSoff = start offset，XSoff = end offset
// Y-axis coordinate offset: YSoff = start offset，YEoff = end offset
#define XSoff 0
#define XEoff 0
#define YSoff 0
#define YEoff 0
/********************************************************************************
* Function Name	: LT268_TFT_SetWindows
* Description  	: Set the area of the window on the screen.
* Input        	: - XStar,yStar: the starting coordinate of the window on the screen
				  - Width,High: width and high of the window on the screen
* Output       	: None
* Return       	: None
*********************************************************************************/
void LT268_TFT_SetWindows(uint16_t XStar, uint16_t yStar, uint16_t Width, uint16_t High)
{
	uint16_t XS, XE, YS, YE;
	XS = XStar + XSoff;
	XE = XStar + XEoff + Width - 1;
	YS = yStar + YSoff;
	YE = yStar + YEoff + High - 1;

	/*X-axis*/
	TFT_CommandWrite(0x2A);
	TFT_DataWrite(XS >> 8);
	TFT_DataWrite(XS);
	TFT_DataWrite(XE >> 8);
	TFT_DataWrite(XE);

	/*Y-axis*/
	TFT_CommandWrite(0x2B);
	TFT_DataWrite(YS >> 8);
	TFT_DataWrite(YS);
	TFT_DataWrite(YE >> 8);
	TFT_DataWrite(YE);

	TFT_CommandWrite(0x2c);
}


//---------------------TFT Sleep Mode----------------------
void ST7789VPanelSleepInMode(void)
{
	TFT_CommandWrite(0x28);
	TFT_CommandWrite(0x10);
	DelayMS(120);
}

//---------------------TFT Sleep Out----------------------
void ST7789VPanelSleepOutMode(void)
{
	TFT_CommandWrite(0x11);
	DelayMS(120);
	TFT_CommandWrite(0x29);
}
//---------------------TFT display on/off ----------------------
void LT268_Display_ON(void)
{
	TFT_CommandWrite(0x29);
}
void LT268_Display_OFF(void)
{
	TFT_CommandWrite(0x28);
}

//------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------
//QSPI_Vincent
/**************************QSPI屏驱动补充部分**************************/
uint8_t qspi_tft_buf[QSPI2_TFT_MAXSIZE] __attribute__((section(".dispaly_buff")));
uint32_t QSPI_BUFF_START[4];
uint16_t pit_urow = 0 ;
uint8_t pit_uflag = 0 ;

void TFT_QSPI_STD_Init(void)
{
	qspi* t = QSPI2;

	t->U32_SSIENR.SSIC_EN = 0;  //失能QSPI0

	t->U32_CTRLR0.SPI_FRF = 0;  //标准SPI模式
	t->U32_CTRLR0.CFS = 0;		//
	t->U32_CTRLR0.SSTE = 0;		//
	t->U32_CTRLR0.SRL = 0;		//
	t->U32_CTRLR0.SLV_OE = 0;	//
	t->U32_CTRLR0.SCPOL = 0;	//0闲置为低电平,1闲置为高电平         （低速用模式0，高速用模式3）
	t->U32_CTRLR0.SCPH = 0;		//数据抓取从一个时钟周期的第二个边沿开始
	t->U32_CTRLR0.FRF = 0;		//摩托罗拉SPI模式
	t->U32_CTRLR0.DFS = 0x07;   //数据格式为8bit
	t->U32_CTRLR0.TMOD = 0;		//0：全双工，1：只发，2只读

//	LTPrintf("CTRLR0:%x \r\n",t->U32_CTRLR0);

	t->U32_CTRLR1.NDF = 0;		//传输数目
	t->U32_BAUDR.SCKDV = TFT_QSPI_DIV;  	//时钟频率
	t->U32_TXFTLR.TXFTHR = 0;   //转移开始FIFO等级
	t->U32_TXFTLR.TFT = 4;		//传输FIFO阈值
	t->U32_RXFTLR.RFT = 4;		//接受FIFO阈值
	t->U32_TXFLR.TXTFL = 0;		//传输FIFO等级
	t->U32_RXFLR.RXTFL = 0;  	//接受FIFO等级

	t->U32_RXSDR.SE = 1;		//1 = negative edge of ssi clk will be used to sample the incoming data
	t->U32_RXSDR.RSD = 0;		//接收数据采样延迟

	t->U32_SPICTRLR0.CLK_STRETCH_EN = 0; //SPI时钟增强
	t->U32_SPICTRLR0.INST_L = 0;		 //命令长度 0:No, 1:4bit, 2:8bit, 3:16bit
	t->U32_SPICTRLR0.ADDR_L = 0;		 //地址长度0:No, 4:16bit, 6:24bit, 8:32bit
	t->U32_SPICTRLR0.WAIT_CYCLES = 0;	 //等待周期
	t->U32_SPICTRLR0.TRANS_TYPE = 0;      //命令和地址的传输类型 0:都单线，  1:命令单线、地址按配置，2:命令和地址都按配置

	t->U32_SSIENR.SSIC_EN = 1;  //使能QSPI0
//	Delay_Ms(1000);
//	LTPrintf("SR:%x \r\n",t->U32_SR);

//------片选部分-------

	if(t == QSPI0)
	{
		CCM->U32_QSPIGPIOCR.QSPI0_SS_GPIOPEN = 1; //片选软件控制
		CCM->U32_QSPIGPIOCR.QSPI0_SS_PUE = 1;//片选上拉
		CCM->U32_QSPIGPIOCR.QSPI0_SS_OBE = 1;//输出模式
	}
	else if(t == QSPI1)
	{
		CCM->U32_QSPIGPIOCR.QSPI1_SS_GPIOPEN = 1; //片选软件控制
		CCM->U32_QSPIGPIOCR.QSPI1_SS_PUE = 1;//片选上拉
		CCM->U32_QSPIGPIOCR.QSPI1_SS_OBE = 1;//输出模式
	}
	else if(t == QSPI2)
	{
		CCM->U32_QSPIGPIOCR.QSPI2_SS_GPIOPEN = 1; //片选软件控制
		CCM->U32_QSPIGPIOCR.QSPI2_SS_PUE = 1;//片选上拉
		CCM->U32_QSPIGPIOCR.QSPI2_SS_OBE = 1;//输出模式
	}

	CS_ST77903_H;
}

UINT16 TFT_QSPI_ReadWriteByte(uint32_t TxData)
{
//	LTPrintf("RWtest\r\n");
	while(QSPI2->U32_SR.TFE == 0)	//等待TX FIFO空
	{
		__asm("nop");
	}
	QSPI2->DR = TxData;	 	  		//发送一个byte
	while( QSPI2->U32_SR.RFNE == 0) 	//等RX FIFO非空，待接收完一个byte
	{
		__asm("nop");
	}
	return QSPI2->DR;          		//返回收到的数据
}

void ST77903_Write_Reg(uint8_t reg)
{
	TFT_QSPI_ReadWriteByte(0xDE);
	TFT_QSPI_ReadWriteByte(0x00);
	TFT_QSPI_ReadWriteByte(reg);
	TFT_QSPI_ReadWriteByte(0x00);
}
void ST77903_Write_Data(uint8_t data)
{
	TFT_QSPI_ReadWriteByte(data);
}

void TFT_QSPI_screen_init(void)
{
	OPTION->U16_CCR.CCRTEST = 1;
	OPTION->U16_CCR.CCRTEST = 2;
	OPTION->U16_CCR.CCRTEST = 3;
	OPTION->U16_CCR.QSPI2EN = 1; // qspi2 enable
	TFT_QSPI_STD_Init();

	//RST set output   int0[3]/ain[3]
	OPTION->U16_ADCCDISR.ADCCDISTEST = 1;
	OPTION->U16_ADCCDISR.ADCCDISTEST = 2;
	OPTION->U16_ADCCDISR.ADCCDISTEST = 3;
	OPTION->U16_ADCCDISR.ADCCDIS |= (1<<3);

	EPORT0->EPDDR |= (1<<3);
	EPORT0->EPPUE |= (1<<3);
	EPORT0->EPDR |= (1<<3);
	DelayMS(10);
	EPORT0->EPDR &=~(1<<3);
	DelayMS(50);
	EPORT0->EPDR |= (1<<3);
	DelayMS(120);

//------- init ------------------------
	//////////////////////////////////////////////////////////xian_c
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xf0);
		ST77903_Write_Data(0xc3);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xf0);
		ST77903_Write_Data(0x96);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xF0);
		ST77903_Write_Data(0xa5);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xe9);
		ST77903_Write_Data(0x20);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xe7);
		ST77903_Write_Data(0x80);
		ST77903_Write_Data(0x77);
		ST77903_Write_Data(0x1f);
		ST77903_Write_Data(0xcc);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xc1);
		ST77903_Write_Data(0x77);
		ST77903_Write_Data(0x07);
		ST77903_Write_Data(0xcf);
		ST77903_Write_Data(0x16);
		CS_ST77903_H;
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xc2);
		ST77903_Write_Data(0x77);
		ST77903_Write_Data(0x07);
		ST77903_Write_Data(0xcf);
		ST77903_Write_Data(0x16);
		CS_ST77903_H;
		DelayUS(5);

		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xc3);
		ST77903_Write_Data(0x22);
		ST77903_Write_Data(0x02);
		ST77903_Write_Data(0x22);
		ST77903_Write_Data(0x04);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xc4);
		ST77903_Write_Data(0x22);
		ST77903_Write_Data(0x02);
		ST77903_Write_Data(0x22);
		ST77903_Write_Data(0x04);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xc5);
		ST77903_Write_Data(0xed);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xe0);
		ST77903_Write_Data( 0x87);
		ST77903_Write_Data( 0x09);
		ST77903_Write_Data( 0x0c);
		ST77903_Write_Data( 0x06);
		ST77903_Write_Data( 0x05);
		ST77903_Write_Data( 0x03);
		ST77903_Write_Data( 0x29);
		ST77903_Write_Data( 0x32);
		ST77903_Write_Data( 0x49);
		ST77903_Write_Data( 0x0f);
		ST77903_Write_Data( 0x1b);
		ST77903_Write_Data( 0x17);
		ST77903_Write_Data( 0x2a);
		ST77903_Write_Data( 0x2f);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xe1);
		ST77903_Write_Data( 0x87);
		ST77903_Write_Data( 0x09);
		ST77903_Write_Data( 0x0c);
		ST77903_Write_Data( 0x06);
		ST77903_Write_Data( 0x05);
		ST77903_Write_Data( 0x03);
		ST77903_Write_Data( 0x29);
		ST77903_Write_Data( 0x32);
		ST77903_Write_Data( 0x49);
		ST77903_Write_Data( 0x0f);
		ST77903_Write_Data( 0x1b);
		ST77903_Write_Data( 0x17);
		ST77903_Write_Data( 0x2a);
		ST77903_Write_Data( 0x2f);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xe5);
		ST77903_Write_Data( 0xbe);
		ST77903_Write_Data( 0xf5);
		ST77903_Write_Data( 0xb1);
		ST77903_Write_Data( 0x22);
		ST77903_Write_Data( 0x22);
		ST77903_Write_Data( 0x25);
		ST77903_Write_Data( 0x10);
		ST77903_Write_Data( 0x22);
		ST77903_Write_Data( 0x22);
		ST77903_Write_Data( 0x22);
		ST77903_Write_Data( 0x22);
		ST77903_Write_Data( 0x22);
		ST77903_Write_Data( 0x22);
		ST77903_Write_Data( 0x22);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xe6);
		ST77903_Write_Data( 0xbe);
		ST77903_Write_Data( 0xf5);
		ST77903_Write_Data( 0xb1);
		ST77903_Write_Data( 0x22);
		ST77903_Write_Data( 0x22);
		ST77903_Write_Data( 0x25);
		ST77903_Write_Data( 0x10);
		ST77903_Write_Data( 0x22);
		ST77903_Write_Data( 0x22);
		ST77903_Write_Data( 0x22);
		ST77903_Write_Data( 0x22);
		ST77903_Write_Data( 0x22);
		ST77903_Write_Data( 0x22);
		ST77903_Write_Data( 0x22);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xec);
		ST77903_Write_Data(0x40);
		ST77903_Write_Data(0x03);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xb2);
		ST77903_Write_Data(0x00);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xb3);
		ST77903_Write_Data(0x01);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xb4);
		ST77903_Write_Data(0x00);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xb5);
		ST77903_Write_Data(0x00);
		ST77903_Write_Data(0x08);
		ST77903_Write_Data(0x00);
		ST77903_Write_Data(0x08);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xa5);
		ST77903_Write_Data(0x00);
		ST77903_Write_Data(0x00);
		ST77903_Write_Data(0x00);
		ST77903_Write_Data(0x00);
		ST77903_Write_Data(0x00);
		ST77903_Write_Data(0x15);
		ST77903_Write_Data(0x2a);
		ST77903_Write_Data(0x8a);
		ST77903_Write_Data(0x02);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xa6);
		ST77903_Write_Data(0x00);
		ST77903_Write_Data(0x00);
		ST77903_Write_Data(0x00);
		ST77903_Write_Data(0x00);
		ST77903_Write_Data(0x00);
		ST77903_Write_Data(0x15);
		ST77903_Write_Data(0x2a);
		ST77903_Write_Data(0x8a);
		ST77903_Write_Data(0x02);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xba);
		ST77903_Write_Data(0x0a);
		ST77903_Write_Data(0x5a);
		ST77903_Write_Data(0x23);
		ST77903_Write_Data(0x10);
		ST77903_Write_Data(0x25);
		ST77903_Write_Data(0x02);
		ST77903_Write_Data(0x00);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xbb);
		ST77903_Write_Data(0x00);
		ST77903_Write_Data(0x30);
		ST77903_Write_Data(0x00);
		ST77903_Write_Data(0x2c);
		ST77903_Write_Data(0x82);
		ST77903_Write_Data(0x87);
		ST77903_Write_Data(0x18);
		ST77903_Write_Data(0x00);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xbc);
		ST77903_Write_Data(0x00);
		ST77903_Write_Data(0x30);
		ST77903_Write_Data(0x00);
		ST77903_Write_Data(0x2c);
		ST77903_Write_Data(0x82);
		ST77903_Write_Data(0x87);
		ST77903_Write_Data(0x18);
		ST77903_Write_Data(0x00);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0xbd);
		ST77903_Write_Data(0xa1);
		ST77903_Write_Data(0xb2);
		ST77903_Write_Data(0x2b);
		ST77903_Write_Data( 0x1a);
		ST77903_Write_Data( 0x56);
		ST77903_Write_Data( 0x43);
		ST77903_Write_Data( 0x34);
		ST77903_Write_Data( 0x65);
		ST77903_Write_Data( 0xff);
		ST77903_Write_Data( 0xff);
		ST77903_Write_Data( 0x0f);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0x35);
		ST77903_Write_Data(0x00);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0x36);  // - - - ML, BGR MH - -
		ST77903_Write_Data(0x0C);//0x0C
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0x3a);
		ST77903_Write_Data(0x05);   //0x07:set RGB888 ; 0x05:565
		CS_ST77903_H;
		DelayUS(5);


		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0x21);
		CS_ST77903_H;
		DelayUS(5);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0x11);
		CS_ST77903_H;
	//	DelayMS(125);
		DelayMS(10);
		CS_ST77903_L;
		DelayUS(5);
		ST77903_Write_Reg(0x29);
		CS_ST77903_H;
		DelayMS(20);
}
	//////////////////////////////////////////////////////////////////////////////////////////////

void TFT_QSPI_Quad_Init(void)
{
	qspi* t = QSPI2;

	t->U32_SSIENR.SSIC_EN = 0;  //失能QSPI0

	t->U32_CTRLR0.SPI_FRF = 2;  //双线模式  0:标准 ，1双线，2四线
	t->U32_CTRLR0.CFS = 0;		//
	t->U32_CTRLR0.SSTE = 0;		//
	t->U32_CTRLR0.SRL = 0;		//
	t->U32_CTRLR0.SLV_OE = 0;	//
	t->U32_CTRLR0.SCPOL = 0;	//0闲置为低电平,1闲置为高电平         （低速用模式0，高速用模式3）
	t->U32_CTRLR0.SCPH = 0;		//数据抓取从一个时钟周期的第二个边沿开始
	t->U32_CTRLR0.FRF = 0;		//摩托罗拉SPI模式

	t->U32_CTRLR1.NDF = 4;		//传输数目
	t->U32_BAUDR.SCKDV = TFT_QSPI_DIV;  	//时钟频率
	t->U32_TXFTLR.TXFTHR = 2;   //转移开始FIFO等级
	t->U32_TXFTLR.TFT = 0;		//传输FIFO阈值
	t->U32_RXFTLR.RFT = 3;		//接受FIFO阈值   // 3
	t->U32_TXFLR.TXTFL = 0;		//传输FIFO等级
	t->U32_RXFLR.RXTFL = 0;  	//接受FIFO等级
	t->U32_RXSDR.SE = 1;		//1 = negative edge of ssi clk will be used to sample the incoming data
	t->U32_RXSDR.RSD = 0;		//接收数据采样延迟  根据时钟频率调整，时钟越快延迟采样延迟越低

	t->U32_CTRLR0.TMOD = 1;		//0：全双工，1：只发，2只读
	t->U32_CTRLR0.DFS = 0x07;   //数据格式为8bit
	t->U32_SPICTRLR0.CLK_STRETCH_EN = 1; //SPI时钟增强
	t->U32_SPICTRLR0.INST_L = 2;		 //命令长度 0:No,1:4bit,2:8bit,3:16bit
	t->U32_SPICTRLR0.ADDR_L = 4;	   //地址长度0:No, 4:16bit, 6:24bit, 8:32bit
	t->U32_SPICTRLR0.WAIT_CYCLES = 0;	 //等待周期
	t->U32_SPICTRLR0.TRANS_TYPE = 0;    //命令和地址的传输类型 0:都单线，  1:命令单线、地址按配置，2:命令和地址都按配置
	t->DMARDLR = 0;
	t->DMATDLR = 0;             //当在传输FIFO中的数据小于等于此设置值，并且TDMAE = 1，则产生发送中断信号

	t->U32_SSIENR.SSIC_EN = 1;  //使能QSPI0

//------片选部分-------
	CCM->U32_QSPIGPIOCR.QSPI2_SS_GPIOPEN = 1; //片选软件控制
	CCM->U32_QSPIGPIOCR.QSPI2_SS_PUE = 1;//片选上拉
	CCM->U32_QSPIGPIOCR.QSPI2_SS_OBE = 1;//输出模式
	CS_ST77903_H;

	/* 开启通道的错误中断，判断配置是否出错 */
	dma_tcd *test_ch = DMA_QSPI2_TX_Channel;
	DMA_Channel_Error_Interrupt_Enable(test_ch);
	EIC_Cmd_Interrupt(EIC_IT_DMAC, Enable);
}

void TFT_QSPI_Quad_DMA_Porch(uint8_t command_bits, uint8_t addr_bits, uint8_t dummy_bits, uint32_t addr, uint32_t num, uint8_t* buf)
{
	qspi* t = QSPI2;
	t->U32_SSIENR.SSIC_EN = 0;  //失能QSPI0
	t->U32_CTRLR1.NDF = ((num == 0) ? 0 : (num - 1));		//传输数目
	t->U32_SPICTRLR0.INST_L = command_bits;		 //命令长度 0:No,1:4bit,2:8bit,3:16bit
	t->U32_SPICTRLR0.ADDR_L = addr_bits;	   //地址长度0:No, 4:16bit, 6:24bit, 8:32bit
	t->U32_SPICTRLR0.WAIT_CYCLES = dummy_bits;	 //等待周期
	t->U32_SSIENR.SSIC_EN = 1;  //使能QSPI0

	dma_tcd *test_ch = DMA_QSPI2_TX_Channel;
	dma_tcd_config_ts dma_tcd_config;
	DMA_TCD_Reset(&dma_tcd_config);  //更改新配置之前必须清空该结构体

	dma_tcd_config.source = (uint32_t)(buf+1);		     // 源地址
	dma_tcd_config.source_modulo = DMA_MOD_Disable;		 // 设0则禁用，设 0<n<=31,则源地址低N位可以变，一般禁用比较鸡肋，无实际应用场合
	dma_tcd_config.source_datasize = DMA_DataSize_8bit;  // 源地址传输长度  0:8bit, 1:16bit, 2:32bit
	dma_tcd_config.source_offset = 1;					 // 每次向总线读取数据后源地址的偏移量 (带符号能向上、向下、不变)
	dma_tcd_config.source_last_address_adjustment = 0;	 // 大循环计数结束后，源地址写回到TCD的偏移量 (带符号能向上、向下、不变)
	/* Source part---End */

	/* Destination part---Start */
	dma_tcd_config.destin = (uint32_t)(&t->DR);		         // 目的地址
	dma_tcd_config.destin_modulo = DMA_MOD_Disable;		 // 设0则禁用，设 0<n<=31,则目的地址低N位可以变，一般禁用比较鸡肋，无实际应用场合
	dma_tcd_config.destin_datasize = DMA_DataSize_8bit;  // 目的地址传输长度 0:8bit, 1:16bit, 2:32bit
	dma_tcd_config.destin_offset = 0;					 // 每次向总线写入数据后目的地址的偏移量 (带符号能向上、向下、不变)
	dma_tcd_config.destin_last_address_adjustment = 0;	 // 大循环计数结束后，目的地址写回到TCD的偏移量 (带符号能向上、向下、不变)
	/* Destination part---End */

	dma_tcd_config.minor_transfer_num = 1; /* 小循环传输数目 */
	/* Major Loop--- */
	dma_tcd_config.major_loop_num = num-1;  /* 小循环次数 */
	dma_tcd_config.d_req = 1;
	/* Interrupt  */
    dma_tcd_config.interrupt_major = Enable; /* 完成大循环启动中断 */

    DMA_Init(test_ch, &dma_tcd_config);
	test_ch->CONTROL_STATUS &=~(1<<0);    // TCD.START = 0 (Must be written last after all other fields have been initialized)

//======================================= DMA ======================================
//	/* 手动清除 通道的done位 */
	DMA_Channel_Clear_Done(test_ch);
	/* 打开通道硬件请求 */
	DMA_Channel_Hardware_Request_Enable(test_ch);  //DMA Set Enable Request Register

//	for (; (t->SR & 0x04) == 0;)
//	{
//		asm("nop");
//	} /* 等待TxFIFO 空 */
	CS_ST77903_L;
	t->DR = 0xDE;
	t->DR = addr;
	t->DR = buf[0];
//	for (; (QSPI2->SR & 0x01) == 0x01;)
//	{
//		asm("nop");
//	} /* 等待QSPI1 空闲 */
	t->U32_DMACR.TDMAE = 1;
}

void TFT_QSPI_Quad_DMA_Line(uint8_t command_bits, uint8_t addr_bits, uint8_t dummy_bits, uint32_t addr, uint32_t num, uint8_t* buf)
{
	qspi* t = QSPI2;
	t->U32_SSIENR.SSIC_EN = 0;  //失能QSPI0
	t->U32_CTRLR1.NDF = ((num == 0) ? 0 : (num - 1));		//传输数目
	t->U32_SPICTRLR0.INST_L = command_bits;		 //命令长度 0:No,1:4bit,2:8bit,3:16bit
	t->U32_SPICTRLR0.ADDR_L = addr_bits;	   //地址长度0:No, 4:16bit, 6:24bit, 8:32bit
	t->U32_SPICTRLR0.WAIT_CYCLES = dummy_bits;	 //等待周期
	t->U32_SSIENR.SSIC_EN = 1;  //使能QSPI0

	dma_tcd *test_ch = DMA_QSPI2_TX_Channel;
	dma_tcd_config_ts dma_tcd_config;
	DMA_TCD_Reset(&dma_tcd_config);  //更改新配置之前必须清空该结构体

	dma_tcd_config.source = (uint32_t)(buf+4);		     // 源地址
	dma_tcd_config.source_modulo = DMA_MOD_Disable;		 // 设0则禁用，设 0<n<=31,则源地址低N位可以变，一般禁用比较鸡肋，无实际应用场合
	dma_tcd_config.source_datasize = DMA_DataSize_32bit;  // 源地址传输长度  0:8bit, 1:16bit, 2:32bit
	dma_tcd_config.source_offset = 4;					 // 每次向总线读取数据后源地址的偏移量 (带符号能向上、向下、不变)
	dma_tcd_config.source_last_address_adjustment = 0;	 // 大循环计数结束后，源地址写回到TCD的偏移量 (带符号能向上、向下、不变)
	/* Source part---End */

	/* Destination part---Start */
	dma_tcd_config.destin = (uint32_t)(&t->DR);		         // 目的地址
	dma_tcd_config.destin_modulo = DMA_MOD_Disable;		 // 设0则禁用，设 0<n<=31,则目的地址低N位可以变，一般禁用比较鸡肋，无实际应用场合
	dma_tcd_config.destin_datasize = DMA_DataSize_8bit;  // 目的地址传输长度 0:8bit, 1:16bit, 2:32bit
	dma_tcd_config.destin_offset = 0;					 // 每次向总线写入数据后目的地址的偏移量 (带符号能向上、向下、不变)
	dma_tcd_config.destin_last_address_adjustment = 0;	 // 大循环计数结束后，目的地址写回到TCD的偏移量 (带符号能向上、向下、不变)
	/* Destination part---End */

	dma_tcd_config.minor_transfer_num = 4; /* 小循环传输数目 */
	/* Major Loop--- */
	dma_tcd_config.major_loop_num = num/4-1;  /* 小循环次数 */
	dma_tcd_config.d_req = 1;
	/* Interrupt  */
    dma_tcd_config.interrupt_major = Enable; /* 完成大循环启动中断 */

    DMA_Init(test_ch, &dma_tcd_config);
	test_ch->CONTROL_STATUS &=~(1<<0);    // TCD.START = 0 (Must be written last after all other fields have been initialized)

//======================================= DMA ======================================
//	/* 手动清除 通道的done位 */
	DMA_Channel_Clear_Done(test_ch);
	/* 打开通道硬件请求 */
	DMA_Channel_Hardware_Request_Enable(test_ch);  //DMA Set Enable Request Register

	CS_ST77903_L;
	t->DR = 0xDE;
	t->DR = addr;
	t->DR = buf[0];
	t->DR = buf[1];
	t->DR = buf[2];
	t->DR = buf[3];
//	for (; (QSPI2->SR & 0x01) == 0x01;)
//	{
//		asm("nop");
//	} /* 等待QSPI1 空闲 */
	t->U32_DMACR.TDMAE = 1;
}

void QSPI1_QSPI2_Priority_Set(void)
{
	dma_channel_priority_ts DMA_CH_Pri;
	DMA_CH_Pri.ch0 = 6;
	DMA_CH_Pri.ch1 = 10;
	DMA_CH_Pri.ch2 = 8;
	DMA_CH_Pri.ch3 = 0;
	DMA_CH_Pri.ch4 = 2;
	DMA_CH_Pri.ch5 = 5;
	DMA_CH_Pri.ch6 = 15;
	DMA_CH_Pri.ch7 = 3;
	DMA_CH_Pri.ch8 = 4;
	DMA_CH_Pri.ch9 = 1;
	DMA_CH_Pri.ch10 = 9;
	DMA_CH_Pri.ch11 = 7;
	DMA_CH_Pri.ch12 = 12;
	DMA_CH_Pri.ch13 = 14;
	DMA_CH_Pri.ch14 = 11;
	DMA_CH_Pri.ch15 = 13;

	ResultStatus res = 0;
	/* 判断配置优先级是否成功 */
	res = DMA_Configuration_Channel_Priority(&DMA_CH_Pri);
//	LTPrintf("res:%d \r\n",res);
	if(res == ERROR)
	{
		LTPrintf("DMA Channel Priority Configuration is Error!!\
				  Can't run the following program!");
		while(1);
	}

	/* 配置各个DMA通道的抢占能力 */
	/* 通道0 能被高优先级的通道挂起，本身不能挂起低优先级的通道 */
	DMA_Configuration_Channel_Preemption(DMA_QSPI1_RX_Channel,DMA_ch_can_be_suspended,DMA_ch_cannot_suspend);
	/* 通道1 不能被高优先级的通道挂起，本身能挂起低优先级的通道 */
	DMA_Configuration_Channel_Preemption(DMA_QSPI2_TX_Channel,DMA_ch_cannot_be_suspended,DMA_ch_can_suspend);
}

void DMA_Handler(void)
{
//	LTPrintf("DMA_Handler \r\n");
	if(Bit_Read(DMA->ESR,DMA_ESR_VLD_MASK))
	{
		LTPrintf("DMA Error!\r\n");
		LTPrintf("ESR:%#x \r\n", DMA->ESR);
		LTPrintf("ERL_ch:%#x \r\n", DMA->ERL);
		uint16_t temp = DMA->ERL;
		DMA->ERL = temp;  /* Clear Error Flag */
	}

	if(DMA_Channel_Check_Interrupt(DMA_QSPI2_TX_Channel) == Set)//Interrupt
	{
		DMA_Channel_Clear_InterruptFlag(DMA_QSPI2_TX_Channel);  //清楚通道的中断标志
		if(pit_uflag == 0)
		{

		}
		else if(pit_uflag == 1)
		{

		}
		else if(pit_uflag == 2)
		{
			if(pit_urow > 0)
			{
				QSPI2->U32_DMACR.TDMAE = 0;
//				for (; (QSPI2->SR & 0x01) == 0x01;) //等待QSPI2 空闲
//				{
//					asm("nop");
//				}
				CS_ST77903_H;
				TFT_QSPI_Quad_DMA_Line(2,6,0,0xDE006000, LCD_XSIZE_TFT*2,&qspi_tft_buf[(LCD_XSIZE_TFT*2)*pit_urow]);
				pit_urow++;
				if(pit_urow>=400)
				{
					pit_uflag = 3;
					pit_urow = 0;
				}
			}
		}
		else if(pit_uflag == 3)
		{
			if(pit_urow == 0)
			{
				QSPI2->U32_DMACR.TDMAE = 0;
//				for (; (QSPI2->SR & 0x01) == 0x01;) //等待QSPI2 空闲
//				{
//					asm("nop");
//				}
				CS_ST77903_H;
				TFT_QSPI_Quad_DMA_Porch(2,4,0,0x0060,4,(uint8_t*)&QSPI_BUFF_START);
				PIT3_EN(DELAY_LINE);
				pit_urow++;
			}
		}
	}
}

